package api

import (
	"OJCenter/global"
	"OJCenter/idl"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"github.com/google/uuid"
	"net/http"
	"strconv"
)

// @Summary	创建竞赛
// @Produce	json
// @Param		contest	body		idl.Contest		true	"竞赛信息//可以少一些字段，具体看数据库"
// @Success	200		{object}	global.Response	""
// @Fail		400  {object} global.Response ""
// @Router		/api/v1/createContest [post]
func (a *Api) CreateContest(c *gin.Context) {
	var Contest idl.Contest

	err := c.ShouldBindJSON(&Contest)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	validate := validator.New()
	err = validate.Struct(&Contest)
	if err != nil {
		global.MarkErrors(err.(validator.ValidationErrors))
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
		return
	}

	Uuid, _ := uuid.NewRandom()
	Contest.Cid = int64(Uuid.ID())

	err = a.M.CreateContest(&Contest)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	global.Res(c, http.StatusOK, global.SUCCESS, new(interface{}))
}

// @Summary	删除竞赛
// @Produce	json
// @Param		cids	body		[]int			true	"竞赛信息//可以少一些字段，具体看数据库"
// @Success	200		{object}	global.Response	""
// @Fail		400  {object} global.Response{Data=[]int64} "返回未删除"
// @Router		/api/v1/deleteContest [post]
func (a *Api) DeleteContest(c *gin.Context) {
	var cids []int64

	err := c.ShouldBindJSON(&cids)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	sum, fu := a.M.DeleteContestByCID(cids)
	if sum != len(cids) {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, fu)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, new(interface{}))
}

// @Summary	更新用户
// @Produce	json
// @Param		contests	body		[]idl.Contest	true	"竞赛信息"
// @Success	200			{object}	global.Response	""
// @Fail		400  {object} global.Response{Data=[]idl.Contest} ""
// @Router		/api/v1/UpdateContest [post]
func (a *Api) UpdateContest(c *gin.Context) {
	var Contest []idl.Contest

	err := c.ShouldBindJSON(&Contest)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	validate := validator.New()
	for _, t := range Contest {
		err := validate.Struct(&t)
		if err != nil {
			global.MarkErrors(err.(validator.ValidationErrors))
			global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
			return
		}
	}

	sum, fu := a.M.UpdateContest(&Contest)
	if sum != len(Contest) {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, fu)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, new(interface{}))
}

// @Summary	获取竞赛列表
// @Produce	json
// @Param		page	query		int									true	"页码"
// @Param		limit	query		int									true	"限制"
// @Success	200		{object}	global.Response{Data=[]idl.Contest}	""
// @Fail		400  {object} global.Response ""
// @Router		/api/v1/getContestList [Get]
func (a *Api) GetContestList(c *gin.Context) {

	limit, _ := strconv.Atoi(c.Query("limit"))
	page, _ := strconv.Atoi(c.Query("page"))

	sum, err := a.M.GetContestList(page, limit)
	if err != nil && sum == nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, sum)
}

// @Summary	竞赛增加题目
// @Produce	json
// @Param		details	body		[]idl.ContestDetailInfo	true	"题目ID"
// @Param		cid		query		int						true	"竞赛ID"
// @Success	200		{object}	global.Response			""
// @Fail		400  {object} global.Response{Data=[]idl.ContestDetailInfo} ""
// @Router		/api/v1/contestAddProblem [post]
func (a *Api) ContestAddProblem(c *gin.Context) {
	var Contest []idl.ContestDetailInfo

	err := c.ShouldBindJSON(&Contest)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	validate := validator.New()
	for _, t := range Contest {
		err := validate.Struct(&t)
		if err != nil {
			global.MarkErrors(err.(validator.ValidationErrors))
			global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
			return
		}
	}

	fails, fu := a.M.CreateContestDetail(&Contest)
	if len(*fails) != 0 {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, fu)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, new(interface{}))
}

// @Summary	竞赛删除题目
// @Produce	json
// @Param		pids	body		[]int			true	"题目ID"
// @Param		cid		query		int				true	"竞赛ID"
// @Success	200		{object}	global.Response	""
// @Fail		400  {object} global.Response{Data=[]int64} ""
// @Router		/api/v1/contestDelProblem [post]
func (a *Api) ContestDelProblem(c *gin.Context) {
	var pids []int64
	cid := c.Query("cid")
	err := c.ShouldBindJSON(&pids)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
	}
	_cid, err := strconv.Atoi(cid)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
	}
	success, fu := a.M.DeleteProblemsFromContent(int64(_cid), pids)
	if success != len(pids) {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, fu)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, nil)
}

// @Summary	竞赛更新题目
// @Produce	json
// @Param		pids	body		[]idl.ContestDetailInfo	true	"题目ID"
// @Success	200		{object}	global.Response			""
// @Fail		400  {object} global.Response{Data=[]idl.ContestDetailInfo} ""
// @Router		/api/v1/contestUpdateProblem [post]
func (a *Api) ContestUpdateProblem(c *gin.Context) {
	var Contest []idl.ContestDetailInfo

	err := c.ShouldBindJSON(&Contest)
	if err != nil {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, err)
		return
	}

	validate := validator.New()
	for _, t := range Contest {
		err := validate.Struct(&t)
		if err != nil {
			global.MarkErrors(err.(validator.ValidationErrors))
			global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, nil)
			return
		}
	}

	fails, fu := a.M.UpdateContestDetails(&Contest)
	if fails != len(Contest) {
		global.Res(c, http.StatusBadRequest, global.INVALID_PARAMS, fu)
		return
	}
	global.Res(c, http.StatusOK, global.SUCCESS, new(interface{}))
}
